<template>
    <div class="w-full">
        <el-upload ref="uploadRef" :accept="accept" v-model:file-list="fileList" class="w-full parent" :auto-upload="false"
            :limit="limit" :multiple="multiple" :on-change="handleChange" :list-type="listType" :on-remove="handleRemove"
            :on-exceed="handleExceed" :on-preview="handlePictureCardPreview" :before-remove="beforeRemove">
        </el-upload>
        <slot name="button">
            <el-button class="w-full">
                <el-icon>
                    <Plus class="fs-14" />
                </el-icon>
                添加附件
            </el-button>
        </slot>
    </div>
    <Teleport to="body">
        <div v-if="dialogVisible" class="shadow-box">
            <!-- <div class="close pointer" @click="dialogVisible = false">
                &times;
            </div> -->
            <div class="img-box">
                <el-image ref="imgRef" class="img" :initial-index="initIndex" :src="dialogImageUrl"
                    :preview-src-list="previews" fit="cover" @close="handleClose" />
            </div>
        </div>
    </Teleport>
</template>
<script>
import { defineComponent } from 'vue'
import { ElMessage, ElMessageBox, genFileId } from 'element-plus'
import * as imageConversion from 'image-conversion';

console.log(2121, genFileId);

export default defineComponent({
    name: 'UploadImage',
    props: {
        accept: {
            type: String,
            default: '.jpg,.jpeg,.png,.gif,.JPG,.JPEG,.PNG,.GIF'
        },
        base64File: {
            type: [String, Array]
        },
        fileUrl: {
            type: [String, Array]
        },
        limit: {
            type: [Number, String],
            default: 1
        },
        multiple: {
            type: Boolean,
            default: false
        },
        listType: {
            type: String,
            default: 'picture-card'
        },
        limitSize: {
            type: Number,
            limit: 2
        },
        exceed: {
            type: Boolean,
            default: false
        },
        canCompress: {
            type: Boolean,
            default: false
        },
        propName: {
            type: String,
            default: ''
        },
        removeConfirm: {
            type: Boolean,
            default: false
        },
        previewList: {
            type: Array,
            default() {
                return []
            }
        }
    },
    components: {

    },
    data() {
        return {
            dialogVisible: false,
            dialogImageUrl: '',
            fileList: [],
            previews: [],
            initIndex: 0
        }
    },
    watch: {
        fileUrl: {
            handler(newval) {
                console.log(666666666, newval);
                if (newval && !Array.isArray(newval)) {
                    this.createFile(newval)
                }
                if (newval && Array.isArray(newval)) {
                    this.fileList = []
                    newval.forEach(i => {
                        this.createFile(i)
                    })
                }
            },
            immediate: true,
            deep: true
        },
        previewList: {
            handler(newval) {
                this.previews = newval || []
            },
            immediate: true,
            deep: true
        }
    },
    methods: {
        async handleChange(file) {
            let rawFile = file.raw
            if (!rawFile) return
            const typeList = this.accept.split(',')
            const fileType = rawFile.name.substring(rawFile.name.lastIndexOf('.'))
            if (typeList.every(i => i !== fileType)) {
                ElMessage.error('只能上传格式为图片的文件')
                fileList.value = []
                return false
            } else if (rawFile.size / 1024 / 1024 > this.limitSize) {
                if (this.canCompress) {
                    rawFile = await imageConversion.compressAccurately(rawFile, (this.limitSize - 1) * 1024)
                } else {
                    ElMessage.error(`只能上传大小为${this.limitSize}M以内的图片`)
                    fileList.value = []
                    return false
                }
            }
            const imgFile = new FileReader()
            imgFile.readAsDataURL(rawFile);
            imgFile.onload = res => {
                let base64 = res.target.result.split('base64,')[1]
                rawFile.base64 = base64
                if (Array.isArray(this.fileUrl)) {
                    // emits('update:base64File', [...props.base64File, base64])
                    this.$emit('success', base64)
                } else {
                    this.$emit('update:base64File', base64)
                }
                this.fileList = []
            };
            return true
        },
        beforeRemove() {
            if (this.removeConfirm) {
                return ElMessageBox.confirm(
                    '是否删除该材料？',
                    '提示',
                    {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                    }
                )
                    .then(
                        () => true,
                        () => false
                    )
            } else {
                return () => true
            }
        },
        handleRemove(file) {
            console.log(2121, file);
            // const list = fileList.value.map(i => {
            //     return i.raw.base64
            // })
            if (Array.isArray(this.fileUrl)) {
                // emits('update:base64File', list)
                this.$emit('remove', file)
            } else {
                this.$emit('update:base64File', '')
            }
        },
        handleExceed(files) {
            console.log(4444, files);
            if (this.exceed) {
                this.$refs.uploadRef.clearFiles()
                const file = files[0]
                file.uid = genFileId()
                this.$refs.uploadRef.handleStart(file)
            } else {
                ElMessage.error({
                    message: `最多只能上传${this.limit}张`
                })
            }
        },
        handlePictureCardPreview(uploadFile) {
            this.dialogImageUrl = uploadFile.url
            this.dialogVisible = true
            setTimeout(() => {
                let cur = this.$refs.imgRef.src
                this.initIndex = this.previewList.findIndex(i => i === cur)
                const dom = this.$refs.imgRef.$refs.container.children[0]
                // dom.style.opacity = 0
                dom.click()
                // imgRef.value.$refs.container.click()
            }, 100);
        },

        getBase64Image(img) {
            const canvas = document.createElement("canvas");
            canvas.width = img.width;
            canvas.height = img.height;
            const ctx = canvas.getContext("2d");
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
            const dataURL = canvas.toDataURL();
            return dataURL;
        },
        createFile(url) {
            const image = new Image()
            let newUrl = url
            if (this.propName) {
                newUrl = url[this.propName]
            }
            image.src = newUrl + '?v=' + Math.random()
            image.crossOrigin = 'anonymous'
            image.onload = () => {
                const fullbase64 = this.getBase64Image(image)
                let base64 = fullbase64.split('base64,')[1]
                if (Array.isArray(this.base64File)) {
                    // emits('update:base64File', [{
                    //     ...url,
                    //     base64
                    // }])
                } else {
                    this.$emit('update:base64File', base64)
                }
            }
            if (typeof url === 'string') {
                this.fileList.push({
                    url: newUrl,
                    uid: url?.fileId ?? genFileId()
                })
            } else {
                this.fileList.push({
                    ...url,
                    url: newUrl,
                    uid: url?.fileId ?? genFileId()
                })
            }
        },
        handleClose() {
            this.dialogVisible = false
        }
    }
})
</script>

<style lang="stylus" scoped>
:deep(.el-upload) {
    width: 100%;
}

:deep(.el-button) {
    border-style: dashed;
}

:deep(.el-upload--picture-card) {
    height: 32px !important;
    border: none;
}

:deep(.w-full .el-upload-list--picture-card) {
    width: 100% !important;
}

:deep(.w-full .el-upload--picture-card) {
    width: 100% !important;
    position: relative;
    background: transparent;
    z-index: 100;
    margin-top: -20px;
}

.shadow-box {
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.5);
    z-index: 10086;
}

.close {
    position: absolute;
    right: 20px;
    top: 20px;
    font-size: 40px;
    color: #fff;
}

.img-box {
    // position: absolute;
    // left: 50%;
    // top: 50%;
    // transform: translate(-50%, -50%);
    // width: auto;
    // max-height: 70vw;
}
.parent {
    position: relative;
}

:deep().el-upload-list__item.is-success:focus:not(:hover) .el-icon--close-tip {
    display: none;
}
:deep().el-image__preview {
    opacity: 0;
    visibility: hidden;
}
</style>